﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.LIB;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class View3DPipeMark : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			Result result;
			try
			{
				if (commandData == null)
				{
					throw new NotImplementedException();
				}
				UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
				Document document = activeUIDocument.Document;
				Selection selection = activeUIDocument.Selection;
				RevitVersionFuncs.ClearSelection(selection);
				SearchBranch searchBranch = new SearchBranch(activeUIDocument);
				transaction = new Transaction(document, "水管标注");
				transaction.Start();
				ISelectionFilter selectionFilter = new PipeFilter();
				Form3DAlighment form3DAlighment = new Form3DAlighment(document);
				if (form3DAlighment.ShowDialog() == DialogResult.OK)
				{
					YJKRevitTools hyrevitTools = new YJKRevitTools();
					if (form3DAlighment.model == 1)
					{
						for (;;)
						{
							try
							{
								Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择要标注的水管");
								Pipe pipe = document.GetElement(reference) as Pipe;
								YJKRevitTools.DeleteTagOfElement(document, BuiltInCategory.OST_PipeTags, pipe);
								Line line = (pipe.Location as LocationCurve).Curve as Line;
								foreach (XYZ xyz in hyrevitTools.getAlignmentPoint(1.0, form3DAlighment.witdh, line, 300.0))
								{
									this.MarkSinglePipe(form3DAlighment.Fs, document, pipe, xyz);
								}
								continue;
							}
							catch (Autodesk.Revit.Exceptions.OperationCanceledException)
							{
								goto IL_20F;
							}
							break;
						}
					}
					searchBranch.PickFirstElement(selectionFilter, "选择一根水管");
					searchBranch.DoSearch();
					ElementNode listRoot = searchBranch.GetListRoot();
					List<ElementNode> list = new List<ElementNode>();
					this.GetAllElemNode(listRoot, ref list);
					foreach (ElementNode elementNode in list)
					{
						Pipe pipe2 = elementNode.Element as Pipe;
						YJKRevitTools.DeleteTagOfElement(document, BuiltInCategory.OST_PipeTags, pipe2);
						Line line2 = (pipe2.Location as LocationCurve).Curve as Line;
						foreach (XYZ xyz2 in hyrevitTools.getAlignmentPoint(form3DAlighment.minLength, form3DAlighment.witdh, line2, 300.0))
						{
							this.MarkSinglePipe(form3DAlighment.Fs, document, pipe2, xyz2);
						}
					}
				}
				IL_20F:
				transaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (transaction != null && 1 == (int)transaction.GetStatus())
				{
					transaction.RollBack();
				}
			}
			return result;
		}

		public void MarkSinglePipe(string tagName, Autodesk.Revit.DB.Document doc, Pipe pipe, XYZ xyz)
		{
			try
			{
				FamilySymbol familySymbol = YJKRevitTools.GetFamilySymbol(doc, tagName, BuiltInCategory.OST_PipeTags);
				if (familySymbol != null)
				{
					IndependentTag independentTag = RevitVersionFuncs.NewTag(doc, doc.ActiveView, new Reference(pipe), false, 0, 0, xyz);
					independentTag.ChangeTypeId(new ElementId(familySymbol.Id.IntegerValue));
					independentTag.HasLeader = false;
				}
				else if (familySymbol == null)
				{
					string text = Path.Combine(Product.InstallLocation, "MarkTagFamily\\PipeTagFamily2013\\" + tagName + ".rfa");
					doc.LoadFamily(text);
					RevitVersionFuncs.NewTag(doc, doc.ActiveView, new Reference(pipe), false, 0, 0, xyz).HasLeader = false;
				}
			}
			catch (Exception)
			{
				throw;
			}
		}

		private List<ElementNode> GetAllElemNode(ElementNode eNode, ref List<ElementNode> listENode)
		{
			if (eNode == null)
			{
				return listENode;
			}
			if (eNode.Element is Pipe)
			{
				listENode.Add(eNode);
			}
			this.GetAllElemNode(eNode.Next, ref listENode);
			if (eNode.SubElementNode != null)
			{
				foreach (ElementNode eNode2 in eNode.SubElementNode)
				{
					this.GetAllElemNode(eNode2, ref listENode);
				}
			}
			return listENode;
		}
	}
}
